tree grammar Hobbes2008TIRBuilder;

options {
 	language = Java;
   	tokenVocab = Hobbes2008;
    	ASTLabelType = CommonTree;
}

@header {
package edu.calvin.djs32.cs214.interpreters.frontend;
import edu.calvin.cs214.hobbes2008.*;
}

@members { 
  protected void mismatch(IntStream input, int ttype, BitSet follow) 
    throws RecognitionException { 
    throw new MismatchedTokenException(ttype, input); 
  } 
  public void recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) 
    throws RecognitionException { 
    throw e; 
  } 
}
@rulecatch { 
  catch (RecognitionException e) { 
    throw e; 
  } 
} 

expression returns [HobbesTIR tir]
@init {
        List expressions = new ArrayList<HobbesTIR>();
}
        : INTEGER { String intstr = (($INTEGER.getText().charAt(0) == '+') ? $INTEGER.getText().substring(1) : $INTEGER.getText()); $tir = new IntegerTIR(Integer.decode(intstr)); }
        | STRING { $tir = new StringTIR($STRING.getText().substring(1, ($STRING.getText().length()-1))); }
        | t = tuple {$tir = t;}
        | ^(APPLICATION (id = identifier t = tuple ))   {$tir = new ApplicationTIR(id, t); }
        | ^(IF ex1=expression ex2=expression ex3=expression) {$tir = new IfTIR(ex1, ex2, ex3); }
        | i = identifier {$tir = i;}
        | ^(LET i=identifier ex1=expression ex2=expression) {$tir = new LetTIR(i, ex1, ex2); }
        | ^(LETFUNC i1=identifier i2=identifier ex1=expression ex2=expression) {LambdaTIR functionLambda = new LambdaTIR(i2, ex1);
        	$tir = new LetFunctionTIR(i1, functionLambda, ex2);}
        ;


tuple returns [TupleTIR tuple]	
@init {
        List expressions = new ArrayList<HobbesTIR>();
}
	:^(TUPLE ( ex=expression { expressions.add(ex); } )*) { $tuple = new TupleTIR(expressions); }
	;

identifier  returns [IdentifierTIR tir]
 	:IDENTIFIER {$tir = new IdentifierTIR($IDENTIFIER.getText()); }	
 	;
